<?php
namespace Controller;

use Model\Rules, Model\Reserve, Exception;

class Index extends Controller {
	/**
	 * 服务器端正常完成请求。
	 * @var int
	 */
	const SUCCESS = 200;
	/**
	 * 服务器端正常完成请求，客户端应停止向服务端发出任何请求。
	 * @var int
	 */
	const SUCCESS_STOP = 201;
	/**
	 * 服务端要求进一步请求。
	 * @var int
	 */
	const ASSORT = 300;
	/**
	 * 验证码错误。
	 * @var int
	 */
	const ERROR_CODE = 400;
	/**
	 * 会话失效。
	 * @var int
	 */
	const ERROR_SESS_INVALID = 401;
	/**
	 * 服务端处理请求异常。
	 * @var int
	 */
	const FAIL = 500;
	/**
	 * 预订失败，重新开始预订。
	 * @var int
	 */
	const FAIL_ORDER = 501;
	/**
	 * 无法正常访问远程系统。
	 * @var int
	 */
	const FAIL_UNABLE = 502;
	/**
	 * 余票不足。
	 * @var int
	 */
	const FAIL_LACK = 503;
	/**
	 * Model\Reserve
	 * @var Model\Reserve
	 */
	private $MReserve = NULL;

	public function __construct() {
		header('Cache-Control: no-store');
		
		if (isset($_GET['sid']) && trim($_GET['sid'])) {
			$this->MReserve = Reserve::getInstance(trim($_GET['sid']));
		}
		if (isset($_POST['sid']) && trim($_POST['sid'])) {
			$this->MReserve = Reserve::getInstance(trim($_POST['sid']));
		}
		
		parent::__construct();
	}

	private function _response($result = 200, $message = '', $ext = '') {
		echo json_encode(['result' => intval($result), 'message' => $message, 'ext' => $ext], JSON_UNESCAPED_UNICODE);
	}

	public function index() {
		if (!function_exists('mb_get_info')) {
			die('Enable mbstring extension.');
		}
		if (!function_exists('curl_getinfo')) {
			die('Enable cURL extension.');
		}
		
		$MRules = Rules::getInstance();
		
		$this->assign('users', Reserve::$user);
		$this->assign('rules', $MRules->getRules());
		
		$this->display();
	}

	public function panel() {
		$_GET['sid'] = isset($_GET['sid']) ? trim($_GET['sid']) : NULL;
		$_GET['user'] = isset($_GET['user']) ? trim($_GET['user']) : NULL;
		$_GET['from'] = isset($_GET['from']) ? trim($_GET['from']) : NULL;
		$_GET['to'] = isset($_GET['to']) ? trim($_GET['to']) : NULL;
		$_GET['dater'] = isset($_GET['dater']) ? trim($_GET['dater']) : NULL;
		
		if (!$_GET['sid']) {
			die('Invalid sid.');
		} elseif (!isset(Reserve::$user[$_GET['user']])) {
			die('Invalid user.');
		} elseif (!$_GET['from']) {
			die('Invalid from.');
		} elseif (!$_GET['to']) {
			die('Invalid to.');
		} elseif (!$_GET['dater']) {
			die('Invalid dater.');
		}
		
		$this->assign($_GET);
		$this->assign('sid', $_GET['sid']);
		$this->assign('name', Reserve::$user[$_GET['user']][0]);
		
		$this->display();
	}

	public function init() {
		try {
			$this->MReserve->init(trim($_GET['from']), trim($_GET['to']), trim($_GET['dater']));
			
			return $this->_response(self::SUCCESS);
		} catch (Exception $e) {
			return $this->_response(self::FAIL, $e->getMessage());
		}
	}

	public function code() {
		if ($_GET['type'] == 'login') {
			echo $this->MReserve->getLoginCode();
		} elseif ($_GET['type'] == 'reserve') {
			echo $this->MReserve->getReserveCode();
		}
	}

	public function login() {
		if (!isset($_GET['code'])) {
			return $this->_response(self::ERROR_CODE);
		}
		
		try {
			return $this->_response(self::SUCCESS, $this->MReserve->login($_GET['user'], trim($_GET['code'])));
		} catch (Exception $e) {
			if (in_array($e->getMessage(), ['远程系统当前访问用户过多', '无法访问远程', '远程系统维护中'])) {
				return $this->_response(self::FAIL_UNABLE, $e->getMessage());
			} elseif ($e->getMessage() == '验证码错误') {
				return $this->_response(self::ERROR_CODE, $e->getMessage());
			} elseif ($e->getCode() == Reserve::ERROR_SESS_INVALID) {
				return $this->_response(self::ERROR_SESS_INVALID, $e->getMessage());
			} else {
				return $this->_response(self::FAIL, $e->getMessage());
			}
		}
	}

	public function detect() {
		$filter = isset($_GET['filter']) ? explode(',', str_replace(['，', '：'], [',', ':'], trim($_GET['filter']))) : [];
		
		try {
			$info = $this->MReserve->detect($filter);
			if ($info) {
				$message = [];
				
				foreach ($info as $seat => $count) {
					if ($seat != 'no' && $seat != 'passenger') {
						$message[] = $seat . '(' . ($count == PHP_INT_MAX ? '充足' : $count) . ')';
					}
				}
				foreach ($info['passenger'] as $name => $value) {
					if ($seat != 'no' && $seat != 'passenger') {
						$message[] = $name . '(' . $value . ')';
					}
				}
				
				return $this->_response(self::SUCCESS, $info['no'] . '：' . implode('，', $message));
			}
			
			return $this->_response(self::ASSORT);
		} catch (Exception $e) {
			if ($e->getMessage() == '无匹配规则') {
				return $this->_response(self::SUCCESS_STOP, $e->getMessage());
			} elseif ($e->getCode() == Reserve::ERROR_SESS_INVALID) {
				return $this->_response(self::ERROR_SESS_INVALID, $e->getMessage());
			}
			
			return $this->_response(self::FAIL, $e->getMessage());
		}
	}

	public function reserve() {
		if (!isset($_GET['code'])) {
			return $this->_response(self::ERROR_CODE);
		}
		
		try {
			$this->MReserve->reserve(trim($_GET['code']));
			
			return $this->_response(self::SUCCESS);
		} catch (Exception $e) {
			if ($e->getMessage() == '远程系统忙') {
				return $this->_response(self::FAIL, '远程系统忙，若多次尝试仍无效，则需要刷新页面并重新登录');
			} elseif ($e->getMessage() == '余票不足') {
				return $this->_response(self::FAIL_LACK);
			} elseif ($e->getCode() == Reserve::ERROR_SESS_INVALID) {
				return $this->_response(self::ERROR_SESS_INVALID);
			} else {
				return $this->_response(self::FAIL, $e->getMessage());
			}
		}
	}

	public function order() {
		try {
			$result = $this->MReserve->order();
			
			if (isset($result['order'])) {
				return $this->_response(self::SUCCESS, '预订成功，订单号：' . $result['order']);
			} elseif (isset($result['error'])) {
				return $this->_response(self::FAIL_ORDER, $result['error']);
			} else {
				if ($result['time'] > 5) {
					$x = ($result['time'] > 60 ? (floor($result['time'] / 60) . '分') : '') . ($result['time'] % 60) . '秒';
					$message = '大约等待：' . $x . '，大约排位：' . $result['count'];
				} else {
					$message = '即将产生结果';
				}
				
				return $this->_response(self::ASSORT, $message);
			}
		} catch (Exception $e) {
			if ($e->getMessage() == '远程系统忙') {
				return $this->_response(self::FAIL, '远程系统忙，若多次尝试仍无效，则需要刷新页面并重新登录');
			} elseif ($e->getCode() == Reserve::ERROR_SESS_INVALID) {
				return $this->_response(self::ERROR_SESS_INVALID);
			} else {
				return $this->_response(self::FAIL, $e->getMessage());
			}
		}
	}

	public function logout() {
		$this->MReserve->destruct();
	}

	public function import() {
		try {
			return $this->_response(self::SUCCESS, '成功导入' . Rules::getInstance()->import() . '条规则');
		} catch (Exception $e) {
			return $this->_response(self::FAIL, $e->getMessage());
		}
	}
}